home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / unarced / graphics / anim / ilbmr.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  7KB  |  194 lines

  1. /*----------------------------------------------------------------------*
  2.  * ILBMR.C  Support routines for reading ILBM files.           11/27/85
  3.  * (IFF is Interchange Format File.)
  4.  *
  5.  * By Jerry Morrison and Steve Shaw, Electronic Arts.
  6.  * This software is in the public domain.
  7.  *
  8.  * This version for the Commodore-Amiga computer.
  9.  *----------------------------------------------------------------------*/
  10. #include "functions.h"
  11. #include "packer.h"
  12. #include "ilbm.h"
  13. #include "stdio.h"
  14.  
  15. int Xoffset,Yoffset;
  16.  
  17. #if 0
  18. #define DEBUGSTUFF
  19. #endif
  20.  
  21. /* ---------- GetCMAP ------------------------------------------------*/
  22. /* pNColorRegs is passed in as a pointer to the number of ColorRegisters
  23.  * caller has space to hold.  GetCMAP sets to the number actually read.*/
  24. IFFP GetCMAP(ilbmContext, colorMap, pNColorRegs)   
  25.       GroupContext *ilbmContext;  WORD *colorMap;  UBYTE *pNColorRegs;
  26.    {
  27.    register long nColorRegs;   
  28.    register IFFP iffp;
  29.    ColorRegister colorReg;
  30.  
  31.    nColorRegs = ilbmContext->ckHdr.ckSize / sizeofColorRegister;
  32.    if (*pNColorRegs < nColorRegs)   nColorRegs = *pNColorRegs;
  33.    *pNColorRegs = nColorRegs;    /* Set to the number actually there.*/
  34.  
  35. #ifdef DEBUGSTUFF
  36.    printf("colorMap.......\n");
  37. #endif
  38.    for ( ;  nColorRegs > 0;  --nColorRegs)  {
  39.       iffp = IFFReadBytes(ilbmContext, (BYTE *)&colorReg
  40.               ,(long)sizeofColorRegister);
  41.       CheckIFFP();
  42.       *colorMap++ = ( (UWORD)( colorReg.red   >> 4 ) << 8 ) |
  43.             ( (UWORD)( colorReg.green >> 4 ) << 4 ) |
  44.             ( (UWORD)( colorReg.blue  >> 4 )      );
  45. #ifdef DEBUGSTUFF
  46.       printf("    %x %x %x\n"
  47.                      ,colorReg.red>>4
  48.                      ,colorReg.green>>4
  49.                      ,colorReg.blue>>4);
  50. #endif
  51.       }
  52.    return(IFF_OKAY);
  53.    }
  54.  
  55. /*---------- GetBODY ---------------------------------------------------*/
  56. /* NOTE: This implementation could be a LOT faster if it used more of the
  57.  * supplied buffer. It would make far fewer calls to IFFReadBytes (and
  58.  * therefore to DOS Read) and to movemem. */
  59. IFFP GetBODY(context, bitmap, mask, bmHdr, buffer, bufsize)
  60.       GroupContext *context;  struct BitMap *bitmap;  BYTE *mask;
  61.       BitMapHeader *bmHdr;  BYTE *buffer;  LONG bufsize;
  62.    {
  63.    register IFFP iffp;
  64.    UBYTE srcPlaneCnt = bmHdr->nPlanes;   /* Haven't counted for mask plane yet*/
  65.    WORD srcRowBytes = RowBytes((long)bmHdr->w);
  66.    LONG bufRowBytes = MaxPackedSize(srcRowBytes);
  67.    long nRows = bmHdr->h;
  68.    long deltabyte,dw,dh;
  69.    Compression compression = bmHdr->compression;
  70.    register long iPlane, iRow, nEmpty;
  71.    register WORD nFilled;
  72.    BYTE *buf, *nullDest, *nullBuf, **pDest;
  73.    BYTE *planes[MaxSrcPlanes]; /* array of ptrs to planes & mask */
  74.  
  75.    deltabyte = bitmap->BytesPerRow - srcRowBytes;
  76. #if 0
  77.    printf("deltabyte: %ld\n",deltabyte);
  78.    printf("compression: %d %d\n"
  79.       ,compression
  80.       ,cmpByteRun1);
  81.    printf("srcrowbytes: %d %d\n"
  82.       ,srcRowBytes
  83.       ,bitmap->BytesPerRow);
  84.    printf("bufsize: %ld %ld\n"
  85.       ,bufsize
  86.       ,bufRowBytes);
  87.    printf("srcplanecnt: %d %d\n"
  88.       ,srcPlaneCnt
  89.       ,MaxSrcPlanes);
  90. #endif
  91.  
  92.    if (compression > cmpByteRun1)
  93.       return(CLIENT_ERROR);
  94.  
  95.    /* Complain if client asked for a conversion GetBODY doesn't handle.*/
  96. #if 0
  97.    if ( srcRowBytes  >  bitmap->BytesPerRow  ||
  98. #endif
  99.    if (    bufsize < bufRowBytes * 2  ||
  100.          srcPlaneCnt > MaxSrcPlanes )
  101.       return(CLIENT_ERROR);
  102.  
  103.    if (nRows > bitmap->Rows)
  104.       nRows = bitmap->Rows;
  105.    
  106.    /* Initialize array "planes" with bitmap ptrs; NULL in empty slots.*/
  107.    Yoffset = bmHdr->y + (bitmap->Rows - bmHdr->pageHeight)/2;
  108.    dh = Yoffset * bitmap->BytesPerRow;
  109.    Xoffset = dw = bmHdr->x
  110.                    + ((bitmap->BytesPerRow - (bmHdr->pageWidth >>3)) >>1);
  111.    for (iPlane = 0; iPlane < bitmap->Depth; iPlane++)
  112.       planes[iPlane] = (BYTE *)bitmap->Planes[iPlane] + dh + dw + (bmHdr->x>>3);
  113. #if 0
  114.                      + bmHdr->y * bitmap->BytesPerRow + (bmHdr->x>>3);
  115. #endif
  116.    for ( ;  iPlane < MaxSrcPlanes;  iPlane++)
  117.       planes[iPlane] = NULL;
  118.  
  119.    /* Copy any mask plane ptr into corresponding "planes" slot.*/
  120.    if (bmHdr->masking == mskHasMask) {
  121.       if (mask != NULL)
  122.          planes[srcPlaneCnt] = mask;  /* If there are more srcPlanes than
  123.                * dstPlanes, there will be NULL plane-pointers before this.*/
  124.       else
  125.          planes[srcPlaneCnt] = NULL;  /* In case more dstPlanes than src.*/
  126.       srcPlaneCnt += 1;  /* Include mask plane in count.*/
  127.       }
  128.  
  129.    /* Setup a sink for dummy destination of rows from unwanted planes.*/
  130.    nullDest = buffer;
  131.    buffer  += srcRowBytes;
  132.    bufsize -= srcRowBytes;
  133.  
  134.    /* Read the BODY contents into client's bitmap.
  135.     * De-interleave planes and decompress rows.
  136.     * MODIFIES: Last iteration modifies bufsize.*/
  137.    buf = buffer + bufsize;  /* Buffer is currently empty.*/
  138.    for (iRow = nRows; iRow > 0; iRow--)  {
  139.       for (iPlane = 0; iPlane < srcPlaneCnt; iPlane++)  {
  140.  
  141.          pDest = &planes[iPlane];
  142.  
  143.          /* Establish a sink for any unwanted plane.*/
  144.          if (*pDest == NULL) {
  145.         nullBuf = nullDest;
  146.             pDest   = &nullBuf;
  147.             }
  148.  
  149.          /* Read in at least enough bytes to uncompress next row.*/
  150.          nEmpty  = buf - buffer;      /* size of empty part of buffer.*/
  151.          nFilled = bufsize - nEmpty;      /* this part has data.*/
  152.      if (nFilled < bufRowBytes) {
  153.         /* Need to read more.*/
  154.  
  155.         /* Move the existing data to the front of the buffer.*/
  156.         /* Now covers range buffer[0]..buffer[nFilled-1].*/
  157.             movmem(buf, buffer, nFilled);  /* Could be moving 0 bytes.*/
  158.  
  159.             if (nEmpty > ChunkMoreBytes(context)) {
  160.                /* There aren't enough bytes left to fill the buffer.*/
  161.                nEmpty = ChunkMoreBytes(context);
  162.                bufsize = nFilled + nEmpty;  /* heh-heh */
  163.                }
  164.  
  165.         /* Append new data to the existing data.*/
  166.             iffp = IFFReadBytes(context, &buffer[nFilled], (long)nEmpty);
  167.             CheckIFFP();
  168.  
  169.             buf     = buffer;
  170.         nFilled = bufsize;
  171.         nEmpty  = 0;
  172.         }
  173.  
  174.          /* Copy uncompressed row to destination plane.*/
  175.          if (compression == cmpNone) {
  176.             if (nFilled < srcRowBytes)  return(BAD_FORM);
  177.         movmem(buf, *pDest, srcRowBytes);
  178.         buf    += srcRowBytes;
  179.             *pDest += srcRowBytes;
  180.             }
  181.      else
  182.          /* Decompress row to destination plane.*/
  183.             if ( UnPackRow(&buf, pDest, nFilled,  srcRowBytes) )
  184.                     /*  pSource, pDest, srcBytes, dstBytes  */
  185.                return(BAD_FORM);
  186.             *pDest += deltabyte;
  187.          }
  188.       }
  189.  
  190.    return(IFF_OKAY);
  191.    }
  192.  
  193.  
  194.